package sy5_Structural_Pattern.composite.transparent;
import java.util.ArrayList;
import java.util.List;
/*
 * 组合模式用于处理树形结构，包含Component（抽象构件）、Leaf（叶子构件）和Composite（容器构件）三个角色。
 * 组合模式描述了如何将容器对象和叶子对象进行递归组合。
 * 通过抽象机制，可以一致地对待容器对象和叶子对象。
 * 本例是透明组合模式。
 */

abstract class Component{  //角色1：抽象构件，表示抽象的根结果
	protected  String name;  //组件名称
	
	public Component(String name) {  //构造方法
		this.name = name;
	}

	protected  abstract void operation();  //业务方法
	protected abstract void add(Component c);  //增加成员
	protected abstract void remove(Component c);	//删除成员
	protected abstract List<Component> getChild();	//获取成员
}

class Leaf extends Component{   //角色2：叶子构件
	public Leaf(String name) {
		super(name);  //调用父类构造方法
	}
	
	@Override
	protected void add(Component c) {
		throw new UnsupportedOperationException(); //可以是空实现
	}
	@Override
	protected void remove(Component c) {
		throw new UnsupportedOperationException(); //可以是空实现
	}
	@Override
	protected List<Component> getChild() {
		throw new UnsupportedOperationException(); //return null;
	}

	@Override
	protected void operation() {  //打印组件名称
		System.out.println(name);
	}
}

class Composite extends Component{  //角色3：容器构件
	protected List<Component> components;

	public Composite(String name) { //构造器
		super(name);
		components=new ArrayList<>();
	}

	@Override
	public void add(Component c) {  
		components.add(c);
	}
	@Override
	protected void remove(Component c) {
		components.remove(c);
	}
	@Override
	protected List<Component> getChild() {   //返回子组件
		return components;
	}

	@Override
	protected void operation() {
		System.out.println("----"+name+"----");
		for(Component c:components) {  //遍历子组件
			c.operation();  //方法递归调用
		}
	}
}

public class Client {  //客户端
	public static void main(String[] args) {
		//所有构件一致地声明
		Component university,computerCollege,infoEngineerCollege;

		//创建根容器组件
		university = new Composite("清华大学");
		//创建2个子容器组件
		computerCollege = new Composite("计算机学院");
		university.add(computerCollege);
		infoEngineerCollege = new Composite("信息工程学院");
		university.add(infoEngineerCollege);
		//创建叶子组件并添加到相应的容器组件
		computerCollege.add(new Leaf("软件工程系"));
		computerCollege.add(new Leaf("网络工程系"));
		computerCollege.add(new Leaf("计算机科学与技术系"));
		infoEngineerCollege.add(new Leaf("通信工程系"));
		infoEngineerCollege.add(new Leaf("电子工程系"));

		university.operation(); //调用递归方法，遍历根容器组件
		//computerCollege.operation(); //调用递归方法，遍历特定子组件
		//new Leaf("计算机科学与技术系（专业）").operation();; //调用递归方法，遍历叶子组件
	}
}
